package com.export.config;

import com.export.bean.model.ExportModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by Studio on 2017/5/11.
 * 工具类
 */
public class FileHandle {

    private static final Logger logger = LoggerFactory.getLogger(FileHandle.class);

    /**
     * 删除单个文件
     * @param   sPath    被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 压缩单个文件
     * @param filepath 文件路径
     * @param zippath 压缩路径
     * */
    public static void ZipFile(String filepath ,String zippath) {
        try {
            File file = new File(filepath);
            File zipFile = new File(zippath);
            InputStream input = new FileInputStream(file);
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            zipOut.putNextEntry(new ZipEntry(file.getName()));
            int temp = 0;
            while((temp = input.read()) != -1){
                zipOut.write(temp);
            }
            input.close();
            zipOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将存放在sourceFilePath目录下的源文件，打包成fileName名称的zip文件，并存放到zipFilePath路径下
     * @param sourceFilePath :待压缩的文件路径
     * @param zipFilePath :压缩后存放路径
     * @param fileName :压缩后文件的名称
     * @return boolean
     */
    public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName){
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;

        if(!sourceFile.exists()){
            logger.error("The uncompressed file directory "+sourceFilePath+"does not exist");
        }else{
            try {
                File zipFile = new File(zipFilePath + "/" + fileName +".zip");
                if(zipFile.exists()){
                    logger.error(zipFilePath + ":The directory already has a file named " + fileName +".zip");
                }else{
                    File[] sourceFiles = sourceFile.listFiles();
                    if(null == sourceFiles || sourceFiles.length<1){
                        logger.error("Uncompressed file directory: no files exist in" + sourceFilePath + ",no compression.");
                    }else{
                        fos = new FileOutputStream(zipFile);
                        zos = new ZipOutputStream(new BufferedOutputStream(fos));
                        byte[] bufs = new byte[1024*10];
                        for(int i=0;i<sourceFiles.length;i++){
                            //创建ZIP实体，并添加进压缩包
                            ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                            zos.putNextEntry(zipEntry);
                            //读取待压缩的文件并写进压缩包里
                            fis = new FileInputStream(sourceFiles[i]);
                            bis = new BufferedInputStream(fis, 1024*10);
                            int read = 0;
                            while((read=bis.read(bufs, 0, 1024*10)) != -1){
                                zos.write(bufs,0,read);
                            }
                        }
                        flag = true;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally{
                //关闭流
                try {
                    if(null != bis) bis.close();
                    if(null != zos) zos.close();
                    if(null != fis) fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }

        }
        return flag;
    }

    /**
     * 删除文件夹及文件夹下所有文件
     * @param path 文件夹
     */
    public static void deleteAllFilesOfDir(File path) {
        while(true){
            System.gc();
            if (!path.exists())
                return;
            if (path.isFile()) {
                path.delete();
                return;
            }
            File[] files = path.listFiles();
            for (int i = 0; i < files.length; i++) {
                deleteAllFilesOfDir(files[i]);
            }
            path.delete();
        }
    }

    /**
     * 获取现在时间
     *
     * @return 返回字符串格式 yyyy-MM-dd HH:mm:ss
     */
    public static String getStringDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }
    /**
     * 获取现在时间
     *
     * @return 返回短时间字符串格式yyyy-MM-dd
     */
    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 创建文件夹
     * @param path 路径
     * @return boolean
     */
    public static boolean createFile(String path){
        File file = new File(path);
        if (!file.exists()) {
            file.mkdir();
            return true;
        }
        return false;
    }

    /**
     * 获取计数器key
     * @param exportModel 导出类
     * @return 计数器名
     */
    public static String getCounter(ExportModel exportModel){
        return "export_user_" + exportModel.getUserId() + ":" + exportModel.getUserName();
    }

    public static Queue<String> getDateRangeByHour(String start, String end) throws Exception{
        Queue<String> queue = new LinkedList<String>();

        Date startDate;
        Date endDate;

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
        SimpleDateFormat stringFormat = new SimpleDateFormat("MM_dd_HH");
        startDate = format.parse(start);
        endDate = format.parse(end);

        Calendar calendar = Calendar.getInstance();

        int hours = (int)((endDate.getTime() - startDate.getTime())/3600000);

        calendar.setTime(startDate);
        queue.offer(Contansts.tableName+"_"+stringFormat.format(calendar.getTime()));

        for(int i = 0;i < hours;i ++){

            calendar.add(Calendar.HOUR_OF_DAY, 1);
            queue.offer(Contansts.tableName+"_"+stringFormat.format(calendar.getTime()));

        }

        return queue;
    }

    public static Queue<String[]> getDateRange(String start, String end) throws Exception{
        Queue<String[]> queue = new LinkedList<String[]>();

        Date startDate;
        Date endDate;

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat stringFormat = new SimpleDateFormat("MM_dd_");
        startDate = format.parse(start);
        endDate = format.parse(end);

        int days = (int)((endDate.getTime() - startDate.getTime())/86400000);

        for(int i = 0;i < days + 1;i ++){
            Date newDate = addDate(startDate, i);
            String[] strings = new String[24];
            for(int j = 0 ;j<24;j++){
                String str = String.format("%02d", j);
                strings[j] = Contansts.tableName+"_"+stringFormat.format(newDate)+str;
            }
            queue.offer(strings);
        }
        return queue;
    }

    public static Date addDate(Date date, long day) throws ParseException {
        long time = date.getTime(); // 得到指定日期的毫秒数
        day = day*24*60*60*1000; // 要加上的天数转换成毫秒数
        time+=day; // 相加得到新的毫秒数
        return new Date(time); // 将毫秒数转换成日期
    }



    private static byte[] readString(String filename) throws IOException {
        File file=new File(filename);

        byte[] buffer;

        FileInputStream in=new FileInputStream(file);
        // size  为字串的长度 ，这里一次性读完
        int size=in.available();
        buffer=new byte[size];
        in.read(buffer);
        in.close();

        return buffer;

    }

}
